#ifndef _CLIENT_H_
#define _CLIENT_H_

#include <xmmsclient/xmmsclient.h>

#include "mcp.h"
#include "mediainfo.h"

class IDInfo;

class Client
    {
  public:
    enum Request
        {
        REQUEST_CURRENT_ID,
        REQUEST_STATUS,
        REQUEST_INDEX,
        REQUEST_CURRENT_INFO,
        REQUEST_PLAYLIST,
        REQUEST_PLAYLIST_INFO,
        REQUEST_VOLUME,
        REQUEST_PLAYTIME
        };

    Client();
    ~Client();

    static const char *userconfdir_get(char *buf, int len);

    /** Returns true if connected.  If needed, attempts to connect/start the server. */
    bool connected(bool check_only=true);
    void disconnect();

  //// Requests and commands
    bool command(Command);
    void request(Request);
    void seek_pending(unsigned int pos);
    void request_playtime(bool enable, bool force=false);
    void request_playlist();
    void request_picture(unsigned int id);
    bool autoupdate_MediaInfo;  // checked after a playlist update
    void change_volume(int value, bool valueIsAbsolute=false);
    void change_volume(int left, int right, bool valueIsAbsolute=false);
    void change_position(unsigned int position_ms);

  //// Information/Status
  //// These return false if the information is not currently available.
    bool playing();
    bool paused();
    bool stopped();
    bool muted();
    MediaInfo *get_current_info();  // returns 0 not available
    bool get_playlist_length(unsigned int *length);
    bool get_playlist_playtime(unsigned int *);
    bool get_playlist_playtime_to_current(unsigned int *);
    bool get_playlist_playtime_after_current(unsigned int *);

    unsigned int get_current_id () { return current_id; }
    unsigned int get_current_position () { return current_index; }
                              
  //// main loop related
    int descriptor();
    bool output_pending();
    void process_output();
    void process_input();
    bool timer_wanted();
    void timer();

protected:
    xmmsc_connection_t *xmms;

    unsigned int current_id;
    unsigned int current_index;
    unsigned int current_status;
    unsigned int left_volume,
                 right_volume,
                 left_muted,
                 right_muted;
//    unsigned int playtime_wait_ms;  not currently implemented
    bool         maintain_playtime;
    unsigned int pending_seek;

    bool         need_playlist;
    IDInfo      *playlist;
    unsigned int playlist_info_req;
    unsigned int playlist_length;
    MediaInfo   *current_info;  // to match xmms2's current playing id

    void playlist_changed();

//    void readMediainfo(xmmsc_result_t *result, unsigned int id, bool complete);
    MediaInfo * find_loaded_mediainfo(unsigned int id);
    void read_Mediainfo(xmmsc_result_t *result, bool playlist_checks);
    void read_playlist(xmmsc_result_t *result);

    friend void xmms_changed_status(xmmsc_result_t *result, void *userdata);
    friend void xmms_changed_id(xmmsc_result_t *result, void *userdata);
    friend void xmms_changed_pos(xmmsc_result_t *result, void *userdata);
    friend void xmms_changed_volume(xmmsc_result_t *result, void *userdata);
    friend void xmms_changed_playlist(xmmsc_result_t *result, void *userdata);
    friend void xmms_changed_mlib(xmmsc_result_t *result, void *userdata);
    friend void xmms_playtime(xmmsc_result_t *result, void *userdata);
    friend void xmms_current_info(xmmsc_result_t *result, void *userdata);
    friend void xmms_playlist_info(xmmsc_result_t *result, void *userdata);
    friend void xmms_read_playlist(xmmsc_result_t *result, void *userdata);
//    friend void read_volume(const void *key, xmmsc_result_value_type_t type,
 //                           const void *value, void *userdata);
 //
    };

#endif // _CLIENT_H_
